package org.stvd.core.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

public class DateUtil {

    public static final SimpleDateFormatEx YMD = new SimpleDateFormatEx("yyyy-MM-dd");
    public static final SimpleDateFormatEx YMD_CN = new SimpleDateFormatEx("yyyy年MM月dd日");
    public static final SimpleDateFormatEx Times = new SimpleDateFormatEx("HH:mm:ss");

    public static final SimpleDateFormatEx Y2DTIME_FORMAT = new SimpleDateFormatEx("yyyy-MM-dd HH:mm:ss");

    public static final SimpleDateFormatEx YMD_HM_FORMAT = new SimpleDateFormatEx("yyyy-MM-dd HH:mm");

    public static final SimpleDateFormatEx Y2CH_FORMAT = new SimpleDateFormatEx("yyyy年MM月dd日 HH时mm分ss秒");

    public static final SimpleDateFormatEx Y2NO_FORMAT = new SimpleDateFormatEx("yyyyMMddHHmmss");

    public static final SimpleDateFormatEx Y2D_FORMAT = new SimpleDateFormatEx("yyyyMMdd");

    public static final SimpleDateFormatEx Y2T_FORMAT = new SimpleDateFormatEx("HHmmss");

    public static final SimpleDateFormatEx YMD_FORMAT = new SimpleDateFormatEx("yyyy-MM-dd");

    public static final SimpleDateFormatEx Y2NO_Mill_FORMAT = new SimpleDateFormatEx("yyyyMMddHHmmssSSS");

    public static final SimpleDateFormatEx Y2SPECIAL_FORMAT = new SimpleDateFormatEx("yyyy.MM.dd");

    public static final SimpleDateFormatEx YEAR_FORMAT = new SimpleDateFormatEx("yyyy");
    public static final SimpleDateFormatEx MONTH_FORMAT = new SimpleDateFormatEx("MM");
    public static final SimpleDateFormatEx DAY_FORMAT = new SimpleDateFormatEx("dd");

    public static String toString(Date date, String pattern) {
        if (date == null || pattern == null) {
            return null;
        }
        return new SimpleDateFormatEx(pattern).format(date);
    }

    public static String getCurrentYear() {
        Calendar calendar = Calendar.getInstance();
        return YEAR_FORMAT.format(calendar.getTime());
    }

    public static String getCurrentMonth() {
        Calendar calendar = Calendar.getInstance();
        return MONTH_FORMAT.format(calendar.getTime());
    }

    public static String getCurrentDay() {
        Calendar calendar = Calendar.getInstance();
        return DAY_FORMAT.format(calendar.getTime());
    }

    public static String getSystemDateOfString() {
        Calendar calendar = Calendar.getInstance();
        return Y2DTIME_FORMAT.format(calendar.getTime());
    }

    public static String getSystemDateOfY2D() {
        Calendar calendar = Calendar.getInstance();
        return Y2D_FORMAT.format(calendar.getTime());
    }

    public static Date getSystemDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static String getSystemDateString() {
        Calendar calendar = Calendar.getInstance();
        return YMD_FORMAT.format(calendar.getTime());
    }

    public static Date getShortDate(String date) {
        try {
            return YMD.parse(date);
        } catch (ParseException e) {
            System.out.print("日期格式不正确!");
        }
        return null;
    }

    public static Date getYmdhmDate(String date) {
        try {
            return YMD_HM_FORMAT.parse(date);
        } catch (ParseException e) {
            System.out.print("日期格式不正确!");
        }
        return null;
    }

    public static Date getDate(String date) {
        try {
            return Y2DTIME_FORMAT.parse(date);
        } catch (ParseException e) {
            System.out.print("日期格式不正确!");
        }
        return getSystemDate();
    }

    /**
     * 日期增加天数获得新的日期
     */
    public static final Date getDateAdd(Date oldDate, int intDay) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(oldDate);
        calendar.add(Calendar.DATE, intDay);
        return calendar.getTime();
    }

    public static boolean beforDate2(String date1, String date2) throws ParseException {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(Y2D_FORMAT.parse(date1));
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(Y2D_FORMAT.parse(date2));

        return calendar1.before(calendar2);
    }

    /**
     * 日期相减
     */
    public static int diffDate(Date date, Date date1) {
        return (int) ((date.getTime() - date1.getTime()) / (24 * 3600 * 1000));
    }

    /**
     * 取得当前日期增加的月数后月份的第一天 比如，当前日期为2009-06-25日，得到增加一个月后日期是7月份的1号 Date date =
     */
    public static Date getMonthAdd(String date, int month) {
        Calendar calendar = Calendar.getInstance();
        try {
            calendar.setTime(DateUtil.YMD.parse(date));
        } catch (ParseException e) {
        }
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.MONTH, month);

        return calendar.getTime();
    }

    /**
     * 日期增加年份获取新的日期 比如，当前日期为2009-12-23日，增加一年后为2010-12-23日 Date date =
     */
    public static Date getYearAdd(Date date, int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, year);
        return calendar.getTime();
    }

    public static Date getMonthAdd(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONDAY, month);
        return calendar.getTime();
    }

    public static Date getMinuteAdd(Date date, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minute);
        return calendar.getTime();
    }

    /**
     * 取得当前月份属于第几季度和季度包含的开始月份和结束月份
     */
    public static String[] getQuarterOfMonth(String month) {
        String[] ret = new String[2];

        String firstQuarter = "01,02,03";
        String secondQuarter = "04,05,06";
        String thirdQuarter = "07,08,09";
        String fourthQuarter = "10,11,12";

        if (firstQuarter.indexOf(month) >= 0) {
            ret = new String[] { "01", "03", "第一季度" };
        }
        if (secondQuarter.indexOf(month) >= 0) {
            ret = new String[] { "04", "06", "第二季度" };
        }
        if (thirdQuarter.indexOf(month) >= 0) {
            ret = new String[] { "07", "09", "第三季度" };
        }
        if (fourthQuarter.indexOf(month) >= 0) {
            ret = new String[] { "10", "12", "第四季度" };
        }

        return ret;
    }

    /**
     * 获取指定日期是星期几
     */
    public static String getDayOfWeek(Date date) {
        String[] week = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return week[calendar.get(Calendar.DAY_OF_WEEK) - 1];
    }

    /**
     * 得到两个日期之间天数
     */
    public static int getDays(String startDate, String endDate) throws ParseException {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(YMD_FORMAT.parse(startDate));
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(YMD_FORMAT.parse(endDate));

        int days = calendar1.get(Calendar.DAY_OF_YEAR) - calendar2.get(Calendar.DAY_OF_YEAR) + 1;

        return days;
    }

    /**
     * 添加计算两日期间的天数(包括头尾日期) 要求输入格式为实例如: 2007-09-25 如果格式输入有误将反回空字符串
     */
    @SuppressWarnings("deprecation")
    public static String countDaysBetweenTwoData(String stratDataStr, String endDataStr) {
        String countDays = "";

        String t1 = stratDataStr.replace('-', '/');
        String t2 = endDataStr.replace('-', '/');

        try {
            Date dt1 = new Date(t1);
            Date dt2 = new Date(t2);
            long l = dt1.getTime() - dt2.getTime();

            long countDay = l / 60 / 60 / 1000 / 24;
            countDays = String.valueOf(countDay + 1);
        } catch (Exception e) {
            return "";
        }
        return countDays;
    }

    /**
     * 得到两个日期之间天数(此格式：yyyy-MM-dd)，不带时分秒
     */
    public static int getDays2(String startDate, String endDate) throws Exception {
        return (int) ((YMD_FORMAT.parse(endDate).getTime() - YMD_FORMAT.parse(startDate).getTime())
                / (24 * 3600 * 1000));
    }

    /**
     * 得到两个日期之间的月份
     */
    public static int getMonths(String startDate, String endDate) throws ParseException {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(YMD_FORMAT.parse(startDate));
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(YMD_FORMAT.parse(endDate));

        return calendar1.get(Calendar.MONTH) - calendar2.get(Calendar.MONTH) + 1;
    }

    /**
     * 得到两个日期之间的月份差 字符串格式为：yyyy-mm-dd
     */
    public static int getMonths2(String startDate, String endDate) throws ParseException {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(YMD_FORMAT.parse(startDate));
        calendar1.add(Calendar.DATE, 1);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(YMD_FORMAT.parse(endDate));

        int years = calendar1.get(Calendar.YEAR) - calendar2.get(Calendar.YEAR);
        int months = calendar1.get(Calendar.MONTH) - calendar2.get(Calendar.MONTH);
        if (calendar1.get(Calendar.DAY_OF_YEAR) < calendar2.get(Calendar.DAY_OF_YEAR)) {
            return years * 12 + months - 1;
        } else {
            return years * 12 + months;
        }

    }

    /**
     * 判断date1在date2之前
     */
    public static boolean beforDate(String date1, String date2) throws ParseException {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(Y2DTIME_FORMAT.parse(date1));
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(Y2DTIME_FORMAT.parse(date2));

        return calendar1.before(calendar2);
    }

    /**
     * 判断date1在date2之后
     */
    public static boolean afterDate(String date1, String date2) throws ParseException {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(Y2DTIME_FORMAT.parse(date1));
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(Y2DTIME_FORMAT.parse(date2));

        return calendar1.after(calendar2);
    }

    /**
     * 判断date1在date2之后
     */
    public static boolean afterDate(Date date1, Date date2) throws ParseException {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date1);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(date2);

        return calendar1.after(calendar2);
    }

    // 当前月的第一天
    public static final Date firstDayOfMonth() {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat datef = new SimpleDateFormat("yyyy-MM-dd");
        cal.set(GregorianCalendar.DAY_OF_MONTH, 1);
        Date beginTime = cal.getTime();
        return DateUtil.getDate(datef.format(beginTime) + " 00:00:00");
    }

    public static final Date lastDayOfMonth() {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat datef = new SimpleDateFormat("yyyy-MM-dd");
        cal.set(Calendar.DATE, 1);
        cal.roll(Calendar.DATE, -1);
        Date endTime = cal.getTime();
        return DateUtil.getDate(datef.format(endTime) + " 23:59:59");
    }

    public static final Date lastDayOfYear(Date currentDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        calendar.set(Calendar.MONTH, 11);
        calendar.set(Calendar.DAY_OF_MONTH, 31);
        return calendar.getTime();
    }

    public static final Date firstDayOfYear(Date currentDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        calendar.set(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }

    /**
     * 将一个字符串统一格式化
     */
    public static final Date formatCSTDateString(String time) throws ParseException {
        Date dt = null;
        try {
            SimpleDateFormat sdfCST = new SimpleDateFormat("EEE MMM dd hh:mm:ss zzz yyyy", Locale.ENGLISH);
            SimpleDateFormat sdfYYYY = new SimpleDateFormat("yyyy-MM-dd");
            if (time.toUpperCase().indexOf("CST") != -1 || time.toUpperCase().indexOf("CDT") != -1) {
                Date date = sdfCST.parse(time);
                String ctime = sdfYYYY.format(date);
                dt = sdfYYYY.parse(ctime);
            } else {
                dt = sdfYYYY.parse(time);
            }
        } catch (ParseException e) {
        }
        return dt;
    }

    public static final String formatCSTDateToString(String time) throws ParseException {
        String dt = null;
        try {
            SimpleDateFormat sdfCST = new SimpleDateFormat("EEE MMM dd hh:mm:ss zzz yyyy", Locale.ENGLISH);
            SimpleDateFormat sdfYYYY = new SimpleDateFormat("yyyyMMddHHmmss.SSSSZ");
            if (time.toUpperCase().indexOf("CST") != -1 || time.toUpperCase().indexOf("CDT") != -1) {
                Date date = sdfCST.parse(time);
                dt = sdfYYYY.format(date);
            } else {
                dt = sdfYYYY.format(time);
            }
        } catch (ParseException e) {
        }
        return dt;
    }

    /**
     * 日期加月
     */
    public static Date getMonthAddInt(String date, int month) {
        Calendar calendar = Calendar.getInstance();
        try {
            calendar.setTime(DateUtil.YMD.parse(date));
        } catch (ParseException e) {
        }
        calendar.add(Calendar.MONTH, month);

        return calendar.getTime();
    }

    /**
     * 根据出生日期计算年龄
     */
    public static int getAge(Date birthDay) throws Exception {
        Calendar cal = Calendar.getInstance();
        if (cal.before(birthDay)) {
            throw new IllegalArgumentException("The birthDay is before Now.It's unbelievable!");
        }
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH);
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birthDay);

        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirth;

        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                // monthNow==monthBirth
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                } else {
                    // do nothing
                }
            } else {
                // monthNow>monthBirth
                age--;
            }
        } else {
            // monthNow<monthBirth
            // donothing
        }
        return age;
    }
}
